package com.inspur.edp.cef.designtime.core.utilsgenerator;

import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityErrorCodeEnum;
import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityException;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class JavaClassInfo {
    private String packageName;
    private ImportInfos importInfos=new ImportInfos();
    private String filePath;

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    private String className;

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    private List<MethodInfo> methods=new ArrayList<>();


    public List<MethodInfo> getMethods() {
        return methods;
    }

    private List<JavaAccessModifier> accessModifiers=new ArrayList<>();

    public List<JavaAccessModifier> getAccessModifiers() {
        return accessModifiers;
    }

    public ImportInfos getImportInfos() {
        return importInfos;
    }

    public void write2File() {
        MetadataProjectService service = SpringBeanUtils.getBean(MetadataProjectService.class);

        String compModulePath = service.getJavaCompProjectPath(filePath);
        String path = Paths.get(compModulePath).resolve(getPackageName().replace(".","\\")).toString();
        String compositePath = path.replace("\\", File.separator);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("package " + this.packageName + ";\n");
        importInfos.write(stringBuilder);
        stringBuilder.append("\n");
        writeClassHeader(stringBuilder);
        writeMethods(stringBuilder);
        writeClassEnd(stringBuilder);

        File folder= new File(compositePath);
        if(folder.exists()==false)
            folder.mkdirs();

        String fileName = compositePath + File.separator + this.className + ".java";
        File f = new File(fileName);

        FileWriter fw;
        try {
            if(f.exists()==false)
                f.createNewFile();
            OutputStreamWriter out = new OutputStreamWriter(
                    new FileOutputStream(f), // true to append
                    "UTF-8"
            );

            out.write(stringBuilder.toString());
            out.flush();
            out.close();
        } catch (IOException e) {
            throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0005, e);
        }
    }

    private void writeMethods(StringBuilder stringBuilder) {
        for(MethodInfo methodInfo:getMethods())
        {
            stringBuilder.append("\n");
            methodInfo.write(stringBuilder);
        }
        stringBuilder.append("\n");
    }

    private void writeClassEnd(StringBuilder stringBuilder) {
        stringBuilder.append("}");
    }

    private void writeClassHeader(StringBuilder stringBuilder) {
        for(JavaAccessModifier accessModifier:getAccessModifiers())
            stringBuilder.append(accessModifier.toString()+" ");
        stringBuilder.append("class ");
        stringBuilder.append(getClassName()).append("{");
    }

    public void addMethodInfo(MethodInfo methodInfo)
    {
        getMethods().add(methodInfo);
        getImportInfos().addImportPackage(methodInfo.getReturnType());
        for(ParameterInfo parameterInfo:methodInfo.getParameters())
            getImportInfos().addImportPackage(parameterInfo.getParamType());
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
}
